<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>EventBus2-4-0源码分析之Post | 清风向阳</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
    <meta name="keywords" content="Joker,Joker's Blog" />
  
  <meta name="description" content="上篇我们介绍了EventBus的注册，这篇我们主要介绍注册之后，EventBus是如何触发事件，传递事件，最后让注册者接受到事件。">
<meta name="keywords" content="Rxjava">
<meta property="og:type" content="article">
<meta property="og:title" content="EventBus2-4-0源码分析之Post">
<meta property="og:url" content="http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/index.html">
<meta property="og:site_name" content="清风向阳">
<meta property="og:description" content="上篇我们介绍了EventBus的注册，这篇我们主要介绍注册之后，EventBus是如何触发事件，传递事件，最后让注册者接受到事件。">
<meta property="og:updated_time" content="2017-09-15T07:00:28.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="EventBus2-4-0源码分析之Post">
<meta name="twitter:description" content="上篇我们介绍了EventBus的注册，这篇我们主要介绍注册之后，EventBus是如何触发事件，传递事件，最后让注册者接受到事件。">
  
  
    <link rel="icon" href="/favicon_pic.ico">
  
  <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="/css/style.css">
  <script src="/js/pace.min.js"></script>
  

  
  

</head>

<body>
  <div id="container">
      <header id="header">
    <div id="banner"></div>
    <div id="header-outer">
        <div id="header-menu" class="header-menu-pos animated">
            <div class="header-menu-container">
                <a href="/" class="left">
                    <span class="site-title">Joker&#39;s Blog</span>
                </a>
                <nav id="header-menu-nav" class="right">
                    
                    <a  href="/">
                        <i class="fa fa-home"></i>
                        <span>Home</span>
                    </a>
                    
                    <a  href="/archives">
                        <i class="fa fa-archive"></i>
                        <span>Archives</span>
                    </a>
                    
                    <a  href="/about">
                        <i class="fa fa-user"></i>
                        <span>About</span>
                    </a>
                    
                </nav>
                <a class="mobile-header-menu-button">
                    <i class="fa fa-bars"></i>
                </a>
            </div>
        </div>
        <div id="header-row">
            <div id="logo">
                <a href="/">
                    <img src="/images/avatar.jpg" alt="logo">
                </a>
            </div>
            <div class="header-info">
                <div id="header-title">
                    
                    <h2>
                        Joker&#39;s Blog
                    </h2>
                    
                </div>
                <div id="header-description">
                    
                    <h3>
                        一个认真的技术博客
                    </h3>
                    
                </div>
            </div>
            <nav class="header-nav">
                <div class="social">
                    
                        <a title="Joker"  href="//joker-studio.pub">
                            <i class="fa fa-home fa-2x"></i></a>
                    
                        <a title="Github" target="_blank" href="//github.com/mjjde">
                            <i class="fa fa-github fa-2x"></i></a>
                    
                </div>
            </nav>
        </div>
    </div>
</header>
      <div class="outer">
        <section id="main" class="body-wrap"><article id="post-EventBus2-4-0源码分析之Post" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 class="post-title" itemprop="name">
      EventBus2-4-0源码分析之Post
    </h1>
    <div class="post-title-bar">
      <ul>
          
              <li>
                  <i class="fa fa-book"></i>
                  
                      <a href="/categories/Android技术/">Android技术</a>
                  
              </li>
          
        <li>
          <i class="fa fa-calendar"></i>  2015-12-25
        </li>
        <li>
          <i class="fa fa-eye"></i>
          <span id="busuanzi_value_page_pv"></span>
        </li>
      </ul>
    </div>
  

          
      </header>
    
    <div class="article-entry post-content" itemprop="articleBody">
      
            
            <blockquote>
<p>上篇我们介绍了EventBus的注册，这篇我们主要介绍注册之后，EventBus是如何触发事件，传递事件，最后让注册者接受到事件。<br><a id="more"></a></p>
<h4 id="EventBust-java"><a href="#EventBust-java" class="headerlink" title="EventBust.java"></a><a href="#EventBust-java" title="EventBust.java"></a>EventBust.java</h4></blockquote>
<p>事件的发起函数我们可以在EventBus类里可以看到。就是 <em>post(Object event)</em> 方法。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">        <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">post</span>(<span class="params">Object <span class="keyword">event</span></span>) </span>&#123;</div><div class="line">    PostingThreadState postingState = currentPostingThreadState.<span class="keyword">get</span>();</div><div class="line">    List&lt;Object&gt; eventQueue = postingState.eventQueue;</div><div class="line">    eventQueue.<span class="keyword">add</span>(<span class="keyword">event</span>);</div><div class="line"></div><div class="line">    <span class="keyword">if</span> (!postingState.isPosting) &#123;</div><div class="line">        postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();</div><div class="line">        postingState.isPosting = <span class="literal">true</span>;</div><div class="line">        <span class="keyword">if</span> (postingState.canceled) &#123;</div><div class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> EventBusException(<span class="string">"Internal error. Abort state was not reset"</span>);</div><div class="line">        &#125;</div><div class="line">        <span class="keyword">try</span> &#123;</div><div class="line">            <span class="keyword">while</span> (!eventQueue.isEmpty()) &#123;</div><div class="line">                postSingleEvent(eventQueue.<span class="keyword">remove</span>(<span class="number">0</span>), postingState);</div><div class="line">            &#125;</div><div class="line">        &#125; <span class="keyword">finally</span> &#123;</div><div class="line">            postingState.isPosting = <span class="literal">false</span>;</div><div class="line">            postingState.isMainThread = <span class="literal">false</span>;</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>该方法的参数是我们之前定义的事件类。往下看我们看到一个类PostingThreadState。</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">final</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">PostingThreadState</span> </span>&#123;</div><div class="line">    <span class="keyword">final</span> <span class="built_in">List</span>&lt;<span class="built_in">Object</span>&gt; eventQueue = <span class="keyword">new</span> ArrayList&lt;<span class="built_in">Object</span>&gt;();</div><div class="line">    boolean isPosting;</div><div class="line">    boolean isMainThread;</div><div class="line">    Subscription subscription;</div><div class="line">    <span class="built_in">Object</span> event;</div><div class="line">    boolean canceled;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>这个类里面保存了事件队列eventQueue，是否正在发送，是否是主线程，订阅者，当前的事件，是否取消，那么这个对象是保存在哪里的呢。</p>
<figure class="highlight aspectj"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">       <span class="keyword">private</span> <span class="keyword">final</span> ThreadLocal&lt;PostingThreadState&gt; currentPostingThreadState = <span class="keyword">new</span> ThreadLocal&lt;PostingThreadState&gt;() &#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="keyword">protected</span> <span class="function">PostingThreadState <span class="title">initialValue</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">return</span> <span class="keyword">new</span> PostingThreadState();</div><div class="line">    &#125;</div><div class="line">&#125;;</div></pre></td></tr></table></figure>
<p>这个对象实例保存在ThreadLocal中，ThreadLocal是用于保存一个线程共用信息，比如子啊主线程中调用的Post方法，那么就会在主线程中保存一个PostingThreadState对象，里面放置发送事件的相关信息。如果是线程池里的一个线程，那么就是该线程保存PostingThreadState。ThreadLocal很好的保存和共享一个线程特有得信息。</p>
<p>好了，我们从当前线程里去除PostingThreadState对象后就把post的event保存在里该对象的list集合里，判断该线程是否还没发送过事件，如果是，就设置postingState.isMainThread和postingState.isPosting = true;然后开启无限循环取出eventQueue里的事件调用 <em>postSingleEvent(eventQueue.remove(0), postingState);</em> 方法。</p>
<figure class="highlight gradle"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line">        <span class="keyword">private</span> <span class="keyword">void</span> postSingleEvent(Object event, PostingThreadState postingState) <span class="keyword">throws</span> Error &#123;</div><div class="line">    <span class="keyword">Class</span>&lt;?&gt; eventClass = event.getClass();</div><div class="line">    <span class="keyword">boolean</span> subscriptionFound = <span class="keyword">false</span>;</div><div class="line">    <span class="keyword">if</span> (eventInheritance) &#123;</div><div class="line">        List&lt;<span class="keyword">Class</span>&lt;?&gt;&gt; eventTypes = lookupAllEventTypes(eventClass);</div><div class="line">        <span class="keyword">int</span> countTypes = eventTypes.<span class="keyword">size</span>();</div><div class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> h = <span class="number">0</span>; h &lt; countTypes; h++) &#123;</div><div class="line">            <span class="keyword">Class</span>&lt;?&gt; clazz = eventTypes.get(h);</div><div class="line">            subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);</div><div class="line">        &#125;</div><div class="line">    &#125; <span class="keyword">else</span> &#123;</div><div class="line">        subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">if</span> (!subscriptionFound) &#123;</div><div class="line">        <span class="keyword">if</span> (logNoSubscriberMessages) &#123;</div><div class="line">            Log.d(TAG, <span class="string">"No subscribers registered for event "</span> + eventClass);</div><div class="line">        &#125;</div><div class="line">        <span class="keyword">if</span> (sendNoSubscriberEvent &amp;&amp; eventClass != NoSubscriberEvent.<span class="keyword">class</span> &amp;&amp;</div><div class="line">                eventClass != SubscriberExceptionEvent.<span class="keyword">class</span>) &#123;</div><div class="line">            post(<span class="keyword">new</span> NoSubscriberEvent(<span class="keyword">this</span>, event));</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>方法里的一个eventInheritance是否支持发送该事件类的父类或者接口类的事件。如果是，就会将事件的父类和接口类都加入到list中准备发送。</p>
<figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line">private <span class="keyword">boolean </span>postSingleEventForEventType(Object event, PostingThreadState postingState, Class&lt;?&gt; eventClass) &#123;</div><div class="line">    CopyOnWriteArrayList&lt;<span class="keyword">Subscription&gt; </span><span class="keyword">subscriptions;</span></div><div class="line">    <span class="keyword">synchronized </span>(this) &#123;</div><div class="line">        <span class="keyword">subscriptions </span>= <span class="keyword">subscriptionsByEventType.get(eventClass);</span></div><div class="line">    &#125;</div><div class="line">    if (<span class="keyword">subscriptions </span>!= null &amp;&amp; !<span class="keyword">subscriptions.isEmpty()) </span>&#123;</div><div class="line">        for (<span class="keyword">Subscription </span><span class="keyword">subscription </span>: <span class="keyword">subscriptions) </span>&#123;</div><div class="line">            postingState.event = event<span class="comment">;</span></div><div class="line">            postingState.<span class="keyword">subscription </span>= <span class="keyword">subscription;</span></div><div class="line">            <span class="keyword">boolean </span>aborted = false<span class="comment">;</span></div><div class="line">            try &#123;</div><div class="line">                postToSubscription(<span class="keyword">subscription, </span>event, postingState.isMainThread)<span class="comment">;</span></div><div class="line">                aborted = postingState.canceled<span class="comment">;</span></div><div class="line">            &#125; finally &#123;</div><div class="line">                postingState.event = null<span class="comment">;</span></div><div class="line">                postingState.<span class="keyword">subscription </span>= null<span class="comment">;</span></div><div class="line">                postingState.canceled = false<span class="comment">;</span></div><div class="line">            &#125;</div><div class="line">            if (aborted) &#123;</div><div class="line">                <span class="keyword">break;</span></div><div class="line">            &#125;</div><div class="line">        &#125;</div><div class="line">        return true<span class="comment">;</span></div><div class="line">    &#125;</div><div class="line">    return false<span class="comment">;</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>这个方法首先去集合里拿有注册这个事件类型的Subscription。这个集合的添加是在register的时候根据onEvent收集的。如果事件被注册过。取出Subscription对象设置postingState.event和postingState.subscription。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">postToSubscription</span>(<span class="params">Subscription subscription, Object <span class="keyword">event</span>, boolean isMainThread</span>) </span>&#123;</div><div class="line">    <span class="keyword">switch</span> (subscription.subscriberMethod.threadMode) &#123;</div><div class="line">        <span class="keyword">case</span> PostThread:</div><div class="line">            invokeSubscriber(subscription, <span class="keyword">event</span>);</div><div class="line">            <span class="keyword">break</span>;</div><div class="line">        <span class="keyword">case</span> MainThread:</div><div class="line">            <span class="keyword">if</span> (isMainThread) &#123;</div><div class="line">                invokeSubscriber(subscription, <span class="keyword">event</span>);</div><div class="line">            &#125; <span class="keyword">else</span> &#123;</div><div class="line">                mainThreadPoster.enqueue(subscription, <span class="keyword">event</span>);</div><div class="line">            &#125;</div><div class="line">            <span class="keyword">break</span>;</div><div class="line">        <span class="keyword">case</span> BackgroundThread:</div><div class="line">            <span class="keyword">if</span> (isMainThread) &#123;</div><div class="line">                backgroundPoster.enqueue(subscription, <span class="keyword">event</span>);</div><div class="line">            &#125; <span class="keyword">else</span> &#123;</div><div class="line">                invokeSubscriber(subscription, <span class="keyword">event</span>);</div><div class="line">            &#125;</div><div class="line">            <span class="keyword">break</span>;</div><div class="line">        <span class="keyword">case</span> Async:</div><div class="line">            asyncPoster.enqueue(subscription, <span class="keyword">event</span>);</div><div class="line">            <span class="keyword">break</span>;</div><div class="line">        <span class="keyword">default</span>:</div><div class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"Unknown thread mode: "</span> + subscription.subscriberMethod.threadMode);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>这个方法我们在上篇已经接触过，是在注册sticky事件的时候主动去调用的。而对于普通的事件是在post的时候调用的。我们来具体的看下这个主要方法。首先判断threadMode。如果当前的线程状态符合onEvent事件触发的要求，那么就会立刻执行 <em>invokeSubscriber(subscription, event)</em> 的方法。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">    <span class="function"><span class="keyword">void</span> <span class="title">invokeSubscriber</span>(<span class="params">Subscription subscription, Object <span class="keyword">event</span></span>) </span>&#123;</div><div class="line">    <span class="keyword">try</span> &#123;</div><div class="line">        subscription.subscriberMethod.method.invoke(subscription.subscriber, <span class="keyword">event</span>);</div><div class="line">    &#125; <span class="keyword">catch</span> (InvocationTargetException e) &#123;</div><div class="line">        handleSubscriberException(subscription, <span class="keyword">event</span>, e.getCause());</div><div class="line">    &#125; <span class="keyword">catch</span> (IllegalAccessException e) &#123;</div><div class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"Unexpected exception"</span>, e);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>该方法就是执行method.invoke的方法很简单。<br>那么不是适合的线程我们会根据要求的ThreadMode. 分别调用mainThreadPoster.enqueue，backgroundPoster.enqueue，asyncPoster.enqueue的方法。</p>
<p>我们先来看下这几个Poster.</p>
<h4 id="HandlerPoster-java"><a href="#HandlerPoster-java" class="headerlink" title="HandlerPoster.java"></a><a href="#HandlerPoster-java" title="HandlerPoster.java"></a>HandlerPoster.java</h4><figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">        <span class="function"><span class="keyword">void</span> <span class="title">enqueue</span>(<span class="params">Subscription subscription, Object <span class="keyword">event</span></span>) </span>&#123;</div><div class="line">    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, <span class="keyword">event</span>);</div><div class="line">    synchronized (<span class="keyword">this</span>) &#123;</div><div class="line">        queue.enqueue(pendingPost);</div><div class="line">        <span class="keyword">if</span> (!handlerActive) &#123;</div><div class="line">            handlerActive = <span class="literal">true</span>;</div><div class="line">            <span class="keyword">if</span> (!sendMessage(obtainMessage())) &#123;</div><div class="line">                <span class="keyword">throw</span> <span class="keyword">new</span> EventBusException(<span class="string">"Could not send handler message"</span>);</div><div class="line">            &#125;</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>PendingPost类是一个拥有next属性的类，next是用来指向下一个PendingPost的，里面有ArrayList集合保存PendingPost。相当于一个缓存池，将用过的PendingPost，保存在集合里，等到下一个需要构建PendingPost的时候不是去new，而是从集合中取出一个来改变里面的event和subscription，这样的优化很常见，就是利用损失一定的内存来换取new的花销。</p>
<figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">Object event<span class="comment">;</span></div><div class="line"><span class="keyword">Subscription </span><span class="keyword">subscription;</span></div><div class="line">PendingPost next<span class="comment">;</span></div><div class="line"></div><div class="line">private PendingPost(Object event, <span class="keyword">Subscription </span><span class="keyword">subscription) </span>&#123;</div><div class="line">    this.event = event<span class="comment">;</span></div><div class="line">    this.<span class="keyword">subscription </span>= <span class="keyword">subscription;</span></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>构造方法里封装了Subscription和event，类中有两个方法，一个是obtainPendingPost，获取一个PendingPost。一个是releasePendingPost。用来释放PendingPost。伴随的是List的remove和add方法。</p>
<p>PendingPostQueue类中保存两个PendingPost，head，tail。当调用enqueue的时候。我们会将要加tail的next指向该pendingPost。同时将tail赋值为该pendingPost。</p>
<figure class="highlight nix"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">        synchronized void enqueue(PendingPost pendingPost) &#123;</div><div class="line">    <span class="keyword">if</span> (<span class="attr">pendingPost</span> == <span class="literal">null</span>) &#123;</div><div class="line">        <span class="built_in">throw</span> new NullPointerException(<span class="string">"null cannot be enqueued"</span>);</div><div class="line">    &#125;</div><div class="line">    <span class="keyword">if</span> (tail != <span class="literal">null</span>) &#123;</div><div class="line">        tail.<span class="attr">next</span> = pendingPost;</div><div class="line">        <span class="attr">tail</span> = pendingPost;</div><div class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="attr">head</span> == <span class="literal">null</span>) &#123;</div><div class="line">        <span class="attr">head</span> = <span class="attr">tail</span> = pendingPost;</div><div class="line">    &#125; <span class="keyword">else</span> &#123;</div><div class="line">        <span class="built_in">throw</span> new IllegalStateException(<span class="string">"Head present, but no tail"</span>);</div><div class="line">    &#125;</div><div class="line">    notifyAll();</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>当调用poll()方法的时候，将head返回，并将head赋值给head指向的PendingPost。<br>这样的数据结构和LinkedList相似。</p>
<p>我们在来看下HandlerPoster的enqueue方法。 调用PendingPost.obtainPendingPost获取一个PendingPost。判断是否已经启动无限循环处理数据，如果没有，就发送一个空消息sendMessage(obtainMessage()），当handler收到消息后就开始无限循环poll数据。应为HandlerPoster是用来处理MainThread上的操作，所以就要在handler里去执行方法。我们看到获取到pendingPost后就去执行 <em>eventBus.invokeSubscriber(pendingPost);</em> 方法了。这样就实现的线程的切换。</p>
<h4 id="AsyncPoster，BackgroundPoster"><a href="#AsyncPoster，BackgroundPoster" class="headerlink" title="AsyncPoster，BackgroundPoster"></a><a href="#AsyncPoster_uFF0CBackgroundPoster" title="AsyncPoster，BackgroundPoster"></a>AsyncPoster，BackgroundPoster</h4><p>这两个Poster和之前的处理方式差不多，差别是要切换的线程不同，一个是UI主线程，所以要使用handler，这两个是要在子线程里去执行，所以都是继承Runnable的，我们在他们的run方法里去处理invokeSubscriber方法，他们之间的区别是BackgroundPoster是有一个队列的，属于并行执行，使用的时候不能有太耗时的操作，这样会使后面的任务一直堵塞。而AsyncPoster，是直接新开启线程去处理，所以不存在阻塞的问题。</p>
<p>下面我们来看下sticky事件的Post.</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postSticky</span>(<span class="params">Object <span class="keyword">event</span></span>) </span>&#123;</div><div class="line">    synchronized (stickyEvents) &#123;</div><div class="line">        stickyEvents.put(<span class="keyword">event</span>.getClass(), <span class="keyword">event</span>);</div><div class="line">    &#125;</div><div class="line">    <span class="comment">// Should be posted after it is putted, in case the subscriber wants to remove immediately</span></div><div class="line">    post(<span class="keyword">event</span>);</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>该方法主要的是将事件存入了stickyEvents集合里，在registerSticky方法注册的时候取出来去执行。我们看到他依然是调用了post方法，这是为了万一使用者希望也能想普通事件一样的触发，当然，如果使用者的registerSticky在别的地方，这里post显然是找不到Subscription的所以就无法执行的。</p>
<p>好了我们关于EventBusde的Post分析就到这了。</p>

            <div class="post-copyright">
    <div class="content">
        <p>最后更新： 2017年09月15日 15:00</p>
        <p>原始链接： <a class="post-url" href="/2015/12/25/EventBus2-4-0源码分析之Post/" title="EventBus2-4-0源码分析之Post">http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/</a></p>
        <footer>
            <a href="http://mjjde.github.io">
                <img src="/images/avatar.jpg" alt="Joker Mei">
                Joker Mei
            </a>
        </footer>
    </div>
</div>

      
    </div>
    <footer class="article-footer">
        
        
<div class="post-share">
    <a href="javascript:;" id="share-sub" class="post-share-fab">
        <i class="fa fa-share-alt"></i>
    </a>
    <div class="post-share-list" id="share-list">
        <ul class="share-icons">
          <li>
            <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/&title=《EventBus2-4-0源码分析之Post》 — 清风向阳&pic=http://mjjde.github.ioimages/avatar.jpg" data-title="微博">
              <i class="fa fa-weibo"></i>
            </a>
          </li>
          <li>
            <a class="weixin share-sns" id="wxFab" href="javascript:;" data-title="微信">
              <i class="fa fa-weixin"></i>
            </a>
          </li>
          <li>
            <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/&title=《EventBus2-4-0源码分析之Post》 — 清风向阳&source=
上篇我们介绍了EventBus的注册，这篇我们主要介绍注册之后，EventBus是如何触发事件，传递事件，最后让注册者接受到事件。" data-title="QQ">
              <i class="fa fa-qq"></i>
            </a>
          </li>
          <li>
            <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/" data-title="Facebook">
              <i class="fa fa-facebook"></i>
            </a>
          </li>
          <li>
            <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《EventBus2-4-0源码分析之Post》 — 清风向阳&url=http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/&via=http://mjjde.github.io" data-title="Twitter">
              <i class="fa fa-twitter"></i>
            </a>
          </li>
          <li>
            <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/" data-title="Google+">
              <i class="fa fa-google-plus"></i>
            </a>
          </li>
        </ul>
     </div>
</div>
<div class="post-modal wx-share" id="wxShare">
    <a class="close" href="javascript:;" id="wxShare-close">×</a>
    <p>扫一扫，分享到微信</p>
    <img src="//api.qrserver.com/v1/create-qr-code/?data=http://mjjde.github.io/2015/12/25/EventBus2-4-0源码分析之Post/" alt="微信分享二维码">
</div>

<div class="mask"></div>

        
        <ul class="article-footer-menu">
            
            
  <li class="article-footer-tags">
    <i class="fa fa-tags"></i>
      
    <a href="/tags/Rxjava/" class="color2">Rxjava</a>
      
  </li>

        </ul>
        
    </footer>
  </div>
</article>


    <aside class="post-toc-pos post-toc-top" id="post-toc">
        <nav class="post-toc-wrap">
            <ol class="post-toc"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#EventBust-java"><span class="post-toc-text">EventBust.java</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#HandlerPoster-java"><span class="post-toc-text">HandlerPoster.java</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#AsyncPoster，BackgroundPoster"><span class="post-toc-text">AsyncPoster，BackgroundPoster</span></a></li></ol>
        </nav>
    </aside>
    

<nav id="article-nav">
  
    <a href="/2015/12/28/Activity的进阶/" id="article-nav-newer" class="article-nav-link-wrap">

      <span class="article-nav-title">
        <i class="fa fa-hand-o-left" aria-hidden="true"></i>
        
          Activity的进阶
        
      </span>
    </a>
  
  
    <a href="/2015/12/23/EventBus2-4-0源码分析之订阅/" id="article-nav-older" class="article-nav-link-wrap">
      <span class="article-nav-title">EventBus2-4-0源码分析之订阅</span>
      <i class="fa fa-hand-o-right" aria-hidden="true"></i>
    </a>
  
</nav>



    
</section>
        
      </div>
      <footer id="footer">
  <div class="outer">
    <div id="footer-info" class="inner">
      
<p>
    <span id="busuanzi_container_site_uv" style='display:none'>
        总访客数：<span id="busuanzi_value_site_uv"></span>
    </span>
    <span id="busuanzi_container_site_pv" style='display:none'>
        总访问量：<span id="busuanzi_value_site_pv"></span>
    </span>
</p>


      <p>
        Powered by  <a href="http://hexo.io/" target="_blank">Hexo</a>
        Theme <a href="//github.com/wongminho/hexo-theme-miho" target="_blank">MiHo</a>
      &copy; 2018 Joker Mei<br>
      </p>
    </div>
  </div>
</footer>
    <script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
  var mihoConfig = {
      root: "http://mjjde.github.io",
      animate: false,
      isHome: false,
      share: true
  }
</script>
<div class="sidebar">
    <!-- <div id="sidebar-search" title="Search">
        <i class="fa fa-search"></i>
    </div> -->
    <div id="sidebar-category" title="Categories">
        <i class="fa fa-book"></i>
    </div>
    <div id="sidebar-tag" title="Tags">
        <i class="fa fa-tags"></i>
    </div>
    <div id="sidebar-top">
        <span class="sidebar-top-icon"><i class="fa fa-angle-up"></i></span>
    </div>
</div>
<div class="sidebar-menu-box" id="sidebar-menu-box">
    <div class="sidebar-menu-box-container">
        <div id="sidebar-menu-box-categories">
            <a class="category-link" href="/categories/Android技术/">Android技术</a><a class="category-link" href="/categories/其他技术/">其他技术</a><a class="category-link" href="/categories/网络技术/">网络技术</a><a class="category-link" href="/categories/设计模式/">设计模式</a>
        </div>
        <div id="sidebar-menu-box-tags">
            <a href="/tags/Activity/" style="font-size: 10px;">Activity</a> <a href="/tags/Android/" style="font-size: 16px;">Android</a> <a href="/tags/Android-IPC/" style="font-size: 10px;">Android-IPC</a> <a href="/tags/Binder/" style="font-size: 16px;">Binder</a> <a href="/tags/DiskLruCache/" style="font-size: 10px;">DiskLruCache</a> <a href="/tags/Fragment/" style="font-size: 10px;">Fragment</a> <a href="/tags/HTTP/" style="font-size: 20px;">HTTP</a> <a href="/tags/Java/" style="font-size: 10px;">Java</a> <a href="/tags/Notification/" style="font-size: 10px;">Notification</a> <a href="/tags/RemoteView/" style="font-size: 10px;">RemoteView</a> <a href="/tags/Rxjava/" style="font-size: 14px;">Rxjava</a> <a href="/tags/ServiceManager/" style="font-size: 14px;">ServiceManager</a> <a href="/tags/android/" style="font-size: 12px;">android</a> <a href="/tags/gradle/" style="font-size: 10px;">gradle</a> <a href="/tags/java/" style="font-size: 18px;">java</a> <a href="/tags/other/" style="font-size: 10px;">other</a> <a href="/tags/volley/" style="font-size: 12px;">volley</a> <a href="/tags/widget/" style="font-size: 10px;">widget</a> <a href="/tags/事件/" style="font-size: 10px;">事件</a> <a href="/tags/组件化/" style="font-size: 10px;">组件化</a> <a href="/tags/设计模式/" style="font-size: 18px;">设计模式</a>
        </div>
    </div>
    <a href="javascript:;" class="sidebar-menu-box-close">&times;</a>
</div>
<div class="mobile-header-menu-nav" id="mobile-header-menu-nav">
    <div id="mobile-header-menu-container">
        <span class="title">Menu</span>
        <ul class="mobile-header-menu-navbar">
            
            <li>
                <a  href="/">
                    <i class="fa fa-home"></i><span>Home</span>
                </a>
            </li>
            
            <li>
                <a  href="/archives">
                    <i class="fa fa-archive"></i><span>Archives</span>
                </a>
            </li>
            
            <li>
                <a  href="/about">
                    <i class="fa fa-user"></i><span>About</span>
                </a>
            </li>
            
        </ul>
    </div>
</div>
<div class="search-wrap">
    <span class="search-close">&times;</span>
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="back">
            <i class="icon icon-lg icon-chevron-left"></i>
        </a>
        <input class="search-field" placeholder="Search..." id="keywords">
        <a id="search-submit" href="javascript:;">
            <i class="fa fa-search"></i>
        </a>
    <div class="search-container" id="search-container">
        <ul class="search-result" id="search-result">
        </ul>
    </div>
</div>

<div id="search-tpl">
    <li class="search-result-item">
        <a href="{url}" class="search-item-li">
            <span class="search-item-li-title" title="{title}">{title}</span>
        </a>
    </li>
</div>
<script src="/js/search.js"></script>
<script src="/js/main.js"></script>








  </div>
</body>
</html>